<template>
    <div v-html="content" style="text-align: left"></div>
</template>

<script setup>
import { onMounted, ref } from 'vue';
import axios from 'axios';
import MarkdownIt from 'markdown-it';
import MarkdownItAbbr from 'markdown-it-abbr';
import MarkdownItAnchor from 'markdown-it-anchor';
import MarkdownItFootnote from 'markdown-it-footnote';
import MarkdownItHighlightjs from 'markdown-it-highlightjs';
import MarkdownItSub from 'markdown-it-sub';
import MarkdownItSup from 'markdown-it-sup';
import MarkdownItTasklists from 'markdown-it-task-lists';
import MarkdownItTOC from 'markdown-it-toc-done-right';
import hljs from 'highlight.js';
import 'highlight.js/styles/github-dark-dimmed.css';
import MarkdownAttrs from 'markdown-it-attrs';
import MarkdownTable from 'markdown-it-multimd-table';
import MarkdownContainer from 'markdown-it-container';
import { full as MarkdownEmoji } from 'markdown-it-emoji';
import Clipboard from 'clipboard';

const markdown = new MarkdownIt({
    html: false,
    xhtmlOut: true,
    typographer: true,
    highlight: function (str, lang) {
        console.log('str --->', str);
        // 当前时间加随机数生成唯一的id标识
        const codeIndex = parseInt(Date.now()) + Math.floor(Math.random() * 10000000);
        // 复制功能主要使用的是 clipboard.js
        let html = `<button class="copy-btn" type="button" data-clipboard-action="copy" data-clipboard-target="#copy${codeIndex}">复制</button>`;
        const linesLength = str.split(/\n/).length - 1;
        // 生成行号
        let linesNum = '<span aria-hidden="true" class="line-numbers-rows">';
        for (let index = 0; index < linesLength; index++) {
            linesNum = linesNum + '<span></span>';
        }
        linesNum += '</span>';
        if (lang && hljs.getLanguage(lang)) {
            try {
                // highlight.js 高亮代码
                const preCode = hljs.highlight(lang, str, true).value;
                html = html + preCode;
                if (linesLength) {
                    html += '<b class="name">' + lang + '</b>';
                }
                // 将代码包裹在 textarea 中，由于防止textarea渲染出现问题，这里将 "<" 用 "&lt;" 代替，不影响复制功能
                return `<pre class="hljs"><code>${html}</code>${linesNum}</pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy${codeIndex}">${str.replace(
                    /<\/textarea>/g,
                    '&lt;/textarea>'
                )}</textarea>`;
            } catch (error) {
                console.log(error);
            }
        }

        const preCode = md.utils.escapeHtml(str);
        html = html + preCode;
        return `<pre class="hljs"><code>${html}</code>${linesNum}</pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy${codeIndex}">${str.replace(
            /<\/textarea>/g,
            '&lt;/textarea>'
        )}</textarea>`;
    },
})
    .use(MarkdownItAbbr)
    .use(MarkdownItAnchor, { permalink: true, permalinkBefore: true, permalinkSymbol: '§' })
    .use(MarkdownItFootnote)
    .use(MarkdownItHighlightjs, { auto: true, hljs: hljs })
    .use(MarkdownItSub)
    .use(MarkdownItSup)
    .use(MarkdownItTasklists, { label: true, labelAfter: true })
    .use(MarkdownItTOC)
    .use(MarkdownTable, {
        multiline: true,
        rowspan: true,
        headerless: true,
        multibody: true,
        aotolabel: true,
    })
    .use(MarkdownContainer)
    .use(MarkdownEmoji)
    .use(MarkdownAttrs);

const props = defineProps({
    content: {
        type: String,
        default: '',
    }
})
// const content = ref('');

const readFileFn = async () => {
    try {
        const res = await axios.get('../src/assets/V1.0.4.md', { responseType: 'text' });
        return res.data;
    } catch (error) {
        throw new Error(error);
    }
};
onMounted(async () => {
    const context = await readFileFn();
    let res = markdown.render(context);
    content.value = res;
    initCopy();
});

let clipboard = '';

const initCopy = () => {
    clipboard = new Clipboard('.copy-btn');
    // 复制成功失败的提示
    clipboard.on('success', e => {
        $message.success('复制成功');
    });
    clipboard.on('error', e => {
        $message.error('复制成功失败');
    });
};
</script>

<style lang="less" scoped>
.hljs {
    padding: 12px 2px 12px 40px !important;
    border-radius: 5px !important;
    position: relative;
    font-size: 14px !important;
    line-height: 22px !important;
    overflow: hidden !important;
    code {
        display: block !important;
        margin: 0 10px !important;
        overflow-x: auto !important;
        &::-webkit-scrollbar {
            z-index: 11;
            width: 6px;
        }
        &::-webkit-scrollbar:horizontal {
            height: 6px;
        }
        &::-webkit-scrollbar-thumb {
            border-radius: 5px;
            width: 6px;
            background: #666;
        }
        &::-webkit-scrollbar-corner,
        &::-webkit-scrollbar-track {
            background: #1e1e1e;
        }
        &::-webkit-scrollbar-track-piece {
            background: #1e1e1e;
            width: 6px;
        }
    }
    .line-numbers-rows {
        position: absolute;
        pointer-events: none;
        top: 12px;
        bottom: 12px;
        left: 0;
        font-size: 100%;
        width: 40px;
        text-align: center;
        letter-spacing: -1px;
        border-right: 1px solid rgba(0, 0, 0, 0.66);
        user-select: none;
        counter-reset: linenumber;
        span {
            pointer-events: none;
            display: block;
            counter-increment: linenumber;
            &:before {
                content: counter(linenumber);
                color: #999;
                display: block;
                text-align: center;
            }
        }
    }
    b.name {
        position: absolute;
        top: 2px;
        right: 50px;
        z-index: 10;
        color: #999;
        pointer-events: none;
    }
    .copy-btn {
        position: absolute;
        top: 2px;
        right: 4px;
        z-index: 10;
        color: #333;
        cursor: pointer;
        background-color: #fff;
        border: 0;
        border-radius: 2px;
    }
}
</style>
